﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;

namespace AGuang.WebTool {
    public class WebClient {
        private System.Net.WebClient client = new System.Net.WebClient();
        private String html;

        public static String UrlDecode(String encodeStr) {
            //正则1：^(?:[\x00-\x7f]|[\xe0-\xef][\x80-\xbf]{2})+$ 
            //正则2：^(?:[\x00-\x7f]|[\xfc-\xff][\x80-\xbf]{5}|[\xf8-\xfb][\x80-\xbf]{4}|[\xf0-\xf7][\x80-\xbf]{3}|[\xe0-\xef][\x80-\xbf]{2}|[\xc0-\xdf][\x80-\xbf])+$
            //如果不考虑哪些什么拉丁文啊，希腊文啊。。。乱七八糟的外文，用短的正则，即正则1
            //如果考虑哪些什么拉丁文啊，希腊文啊。。。乱七八糟的外文，用长的正则，即正则2
            //本方法使用的正则2
            String matchStr = @"^(?:[\x00-\x7f]|[\xfc-\xff][\x80-\xbf]{5}|[\xf8-\xfb][\x80-\xbf]{4}|[\xf0-\xf7][\x80-\xbf]{3}|[\xe0-\xef][\x80-\xbf]{2}|[\xc0-\xdf][\x80-\xbf])+$";
            if (Regex.IsMatch(HttpUtility.UrlDecode(encodeStr, Encoding.GetEncoding("iso-8859-1")), matchStr)) {
                return HttpUtility.UrlDecode(encodeStr, Encoding.GetEncoding("UTF-8"));
            } else {
                return HttpUtility.UrlDecode(encodeStr, Encoding.GetEncoding("GB2312"));
            }
        }

        /// <summary>
        /// 用指定编码读取网页的内容
        /// </summary>
        /// <param name="url">网址</param>
        /// <param name="encoding">编码</param>
        public WebClient(String url, Encoding encoding) {
            Stream stream = client.OpenRead(url);
            StreamReader reader = new StreamReader(stream, encoding);
            html = reader.ReadToEnd();
            reader.Close();
            stream.Close();
        }

        /// <summary>
        /// 用指定编码读取网页的内容
        /// </summary>
        /// <param name="url">网址</param>
        /// <param name="encoding">编码</param>
        public WebClient(String url, String charset):this(url,Encoding.GetEncoding(charset)) { }

        /// <summary>
        /// 用默认编码读取网页的内容
        /// </summary>
        /// <param name="url">网址</param>
        public WebClient(String url) : this(url, Encoding.Default) { }

        /// <summary>
        /// 获取网页的全部内容
        /// </summary>
        /// <returns>HTML</returns>
        public String GetHTML() {
            return html;
        }

        /// <summary>
        /// 获取网页的部分内容（包含开始字符和结束字符）
        /// </summary>
        /// <param name="start">开始字符</param>
        /// <param name="end">结束字符</param>
        /// <returns>所需要的部分</returns>
        public String GetSubHtml(String start,String end){
            SubHtmlResult result = GetSubHtml(0, start, end);
            if (result == null) return null;
            return result.Html;
        }

        /// <summary>
        /// 获取网页的部分内容
        /// </summary>
        /// <param name="start">开始字符</param>
        /// <param name="end">结束字符</param>
        /// <param name="withOutStartAndEnd">是否不包含开始字符和结束字符</param>
        /// <returns>所需要的部分</returns>
        public String GetSubHtml(String start, String end, bool withOutStartAndEnd) {
            SubHtmlResult result = GetSubHtml(0, start, end, withOutStartAndEnd);
            if (result == null) return null;
            return result.Html;
        }

        /// <summary>
        /// 获取网页的部分内容
        /// </summary>
        /// <param name="start">开始字符</param>
        /// <param name="end">结束字符</param>
        /// <param name="withOutStartAndEnd">是否不包含开始字符和结束字符</param>
        /// <returns>所需要的部分</returns>
        public SubHtmlResult GetSubHtml(String html, int index, String start, String end, bool withOutStartAndEnd) {
            if (!withOutStartAndEnd) return GetSubHtml(html,index,start, end);
            int startIndex = html.IndexOf(start,index);
            if (startIndex == -1) return null;
            int endIndex = html.IndexOf(end, startIndex + start.Length);
            if (endIndex <= startIndex) return null;
            SubHtmlResult result = new SubHtmlResult();
            result.Html = html.Substring(startIndex + start.Length, endIndex - startIndex - start.Length);
            result.EndIndex = endIndex + end.Length;
            return result;
        }

        /// <summary>
        /// 获取网页的部分内容（包含开始字符和结束字符）
        /// </summary>
        /// <param name="start">开始字符</param>
        /// <param name="end">结束字符</param>
        /// <returns>所需要的部分</returns>
        public SubHtmlResult GetSubHtml(String html,int index, String start, String end) {
            int startIndex = html.IndexOf(start,index);
            if (startIndex == -1) return null;
            int endIndex = html.IndexOf(end, startIndex + start.Length);
            if (endIndex <= startIndex) return null;
            SubHtmlResult result = new SubHtmlResult();
            result.Html=html.Substring(startIndex, endIndex - startIndex + end.Length);
            result.EndIndex = endIndex + end.Length;
            return result;
        }


        /// <summary>
        /// 获取网页的部分内容
        /// </summary>
        /// <param name="start">开始字符</param>
        /// <param name="end">结束字符</param>
        /// <param name="withOutStartAndEnd">是否不包含开始字符和结束字符</param>
        /// <returns>所需要的部分</returns>
        public SubHtmlResult GetSubHtml(int index, String start, String end, bool withOutStartAndEnd) {
            return GetSubHtml(html, index, start, end, withOutStartAndEnd);
        }

        /// <summary>
        /// 获取网页的部分内容（包含开始字符和结束字符）
        /// </summary>
        /// <param name="start">开始字符</param>
        /// <param name="end">结束字符</param>
        /// <returns>所需要的部分</returns>
        public SubHtmlResult GetSubHtml(int index, String start, String end) {
            return GetSubHtml(html, index, start, end);
        }


        /// <summary>清理资源</summary>
        ~WebClient() {
            client.Dispose();
        }

        /// <summary>截取html的内容</summary>
        public class SubHtmlResult {
            private String html;
            private int endIndex;

            /// <summary>截取html的文字内容</summary>
            public String Html { get { return html; } set { html = value; } }
            /// <summary>截取html的结束位置</summary>
            public int EndIndex { get { return endIndex; } set { endIndex = value; } }
        }
    }
}
